package org.jeecg.modules.wangyue.payment.alipay.controller;

import com.alibaba.druid.support.json.JSONUtils;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayConstants;
import com.alipay.api.internal.util.AlipaySignature;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.wangyue.constant.DelFlagConstant;
import org.jeecg.modules.wangyue.constant.IsVipConstant;
import org.jeecg.modules.wangyue.constant.OrderStatusConstant;
import org.jeecg.modules.wangyue.entity.IndentJs;
import org.jeecg.modules.wangyue.entity.IndentVip;
import org.jeecg.modules.wangyue.entity.UserBasic;
import org.jeecg.modules.wangyue.mapper.IndentJsMapper;
import org.jeecg.modules.wangyue.mapper.IndentVipMapper;
import org.jeecg.modules.wangyue.model.req.ReqCommonModel;
import org.jeecg.modules.wangyue.payment.alipay.config.AlipayConfig;
import org.jeecg.modules.wangyue.payment.alipay.request.AlipayBackRequest;
import org.jeecg.modules.wangyue.payment.alipay.service.IAlipayService;
import org.jeecg.modules.wangyue.service.IIndentJsService;
import org.jeecg.modules.wangyue.service.IUserBasicService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 62377
 */
@Slf4j
@Api(tags = "支付宝回调")
@RestController
@RequestMapping("/wangyue/app2/payment/alipay/")
public class AlipayNotifyController {
    @Resource
    private AlipayConfig alipayConfig;

    @Autowired
    private IAlipayService iAlipayService;

    @Resource
    private IIndentJsService indentJsService;

    @Autowired
    private IndentJsMapper indentJsMapper;

    @Autowired
    private IUserBasicService iUserBasicService;

    @Autowired
    private IndentVipMapper indentVipMapper;


    /**
     * 完成支付后的同步通知
     * 页面跳转同步通知页面路径，接收支付宝回调后，再封装页面数据，直接返回相应页面到前端
     */
    @PostMapping("/return")
    public Result<T> callBack(AlipayBackRequest alipayBackRequest) {
        log.info("=========支付宝同步返回========");
        log.info("同步通知");
        if ("9000".equals(alipayBackRequest.getResultStatus())) {
            iAlipayService.callBack(alipayBackRequest);
            //TODO 调用支付后订单状态修改
            return Result.OK("Success");
        } else {
            return Result.error("Fail");
        }
    }

    /**
     * 完成支付后的异步通知
     * 页面跳转异步通知页面路径，接收支付宝回调后，再封装页面数据，直接返回相应页面到前端
     */
    @PostMapping("/notify")  // 注意这里必须是POST接口
    public void payNotify(HttpServletRequest request, HttpServletResponse response) throws IOException {
        System.out.println("=========支付宝异步回调========");
        PrintWriter out = response.getWriter();
        try {
            Map<String, String> params = new HashMap<>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (String map : requestParams.keySet()) {
                params.put(map, requestParams.get(map)[0]);
            }
            log.info("支付宝回调，{}", JSONUtils.toJSONString(params));
            // 支付宝验签
            boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayConfig.getPublicKey(), AlipayConstants.CHARSET_UTF8, AlipayConstants.SIGN_TYPE_RSA2);
            /*
             * 实际验证过程建议商户务必添加以下校验：
             */
            if (signVerified) {
                // 验签通过
                //商户网站唯一订单号
                String outTradeNo = params.get("out_trade_no");
                log.info("订单号：" + outTradeNo);
                /*
                 * 交易状态
                 * TRADE_SUCCESS 交易完成
                 * TRADE_FINISHED 支付成功
                 * WAIT_BUYER_PAY 交易创建
                 * TRADE_CLOSED 交易关闭
                 */
                String tradeStatus = params.get("trade_status");
                log.info("订单状态：" + tradeStatus);
                if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)) {
                    if ("JS".equals(outTradeNo.substring(0, 2))) { //技师订单
                        QueryWrapper<IndentJs> indentJsQueryWrapper = new QueryWrapper<>();
                        indentJsQueryWrapper.eq("order_no", outTradeNo);
                        String sql = "(order_status = '" + OrderStatusConstant.toBePaid + "' or order_status = '" + OrderStatusConstant.closePaid + "')";
                        indentJsQueryWrapper.apply(sql);
                        indentJsQueryWrapper.eq("del_flag", DelFlagConstant.normal);
                        IndentJs indentJs = indentJsMapper.selectOne(indentJsQueryWrapper);
                        if (oConvertUtils.isNotEmpty(indentJs)) {
                            ReqCommonModel reqCommonModel = new ReqCommonModel();
                            reqCommonModel.setId(indentJs.getId());
                            indentJsService.changeToBeServed(reqCommonModel);
                        } else {
                            log.error("订单:" + outTradeNo + "已支付！");
                        }
                    } else if("VIP".equals(outTradeNo.substring(0, 3))) { //vip会员订单
                        //通过订单号查询出userId数据
                        QueryWrapper<IndentVip> indentVipQueryWrapper = new QueryWrapper<>();
                        indentVipQueryWrapper.eq("order_no", outTradeNo);
                        indentVipQueryWrapper.eq("del_flag", DelFlagConstant.normal);
                        IndentVip indentVip = indentVipMapper.selectOne(indentVipQueryWrapper);
                        if(oConvertUtils.isEmpty(indentVip)){
                            //先判断是否开通vip，如果没开通，可继续执行VIP开通操作
                            QueryWrapper<UserBasic> userBasicQueryWrapper = new QueryWrapper<>();
                            userBasicQueryWrapper.eq("id", indentVip.getUserId());
                            userBasicQueryWrapper.eq("del_flag", DelFlagConstant.normal);
                            UserBasic userBasic = iUserBasicService.getOne(userBasicQueryWrapper);
                            if(oConvertUtils.isNotEmpty(userBasic) && IsVipConstant.no.equals(userBasic.getIsVip())){ //未开通VIP会员
                                iUserBasicService.openVip(outTradeNo);
                            }else {
                                log.error("订单:" + outTradeNo + "已支付，或该用户已开通VIP会员！");
                            }
                        }else{
                            log.error("订单:" + outTradeNo + "数据未查到！");
                        }
                    } else {
                        log.info("订单:"+outTradeNo+"没有配置异步回调处理！");
                    }
                    log.info("调用成功");
                    out.print("success");
                } else if ("TRADE_CLOSED".equals(tradeStatus)) {
                    log.error("订单关闭！");
                    out.print("success");
                    /*response.getOutputStream().write("success".getBytes());
                    response.flushBuffer();*/
                    //return "success";
                } else {
                    log.error("调用失败");
                    out.print("fail");
                }
                //给支付宝返回success,否则支付宝会连续多次发送
                /*response.getOutputStream().write("success".getBytes());
                response.flushBuffer();*/
                //return "success";
            } else {
                //失败给支付宝返回fail,支付宝重试
                /*response.getOutputStream().write("fail".getBytes());
                response.flushBuffer();*/
                //return "fail";
                out.print("fail");
            }
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
    }

}
